home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / X11R4 / cmds / X / ddx / sprite.X11R3 / spriteKbd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-10-08  |  19.2 KB  |  695 lines

  1. /*-
  2.  * spriteKbd.c --
  3.  *    Functions for retrieving data from a keyboard.
  4.  *
  5.  * Copyright (c) 1987 by the Regents of the University of California
  6.  *
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  *
  15.  *
  16.  */
  17. #ifndef lint
  18. static char rcsid[] =
  19.     "$Header: /a/X/src/cmds/Xsprite/ddx/sun3.md/RCS/spriteKbd.c,v 5.4 88/10/01 10:39:05 ouster Exp Locker: ouster $ SPRITE (Berkeley)";
  20. #endif lint
  21.  
  22. #define Time SpriteTime
  23. #include <fs.h>
  24. #undef Time
  25.  
  26. #define NEED_EVENTS
  27. #include    "spriteddx.h"
  28.  
  29. #include    <bit.h>
  30.  
  31. #include    <errno.h>
  32. #include    <fcntl.h>
  33. #include    <sys/file.h>
  34. #include    <sys/time.h>
  35.  
  36. #include    "keysym.h"
  37.  
  38. #define AUTO_GENERATED    0x10000
  39.  
  40. #define MIN_KEYCODE    8       /* Keycode below which we may not transmit */
  41.  
  42. /*
  43.  * Keycode that means "all keys are now up":
  44.  */
  45.  
  46. #define ALL_KEYS_UP    127
  47.  
  48. static void        spriteBell();
  49. static void        spriteKbdCtrl();
  50. static Mouse_Event    *spriteKbdGetEvents();
  51. static void        spriteKbdProcessEvent();
  52. static void        spriteKbdDoneEvents();
  53.  
  54. /*
  55.  * Auto-repeat stuff.
  56.  */
  57. static enum {
  58.     REPEAT_LONG,        /* Start repeat with long timeout */
  59.     REPEAT_SHORT,        /* Start repeat with short timeout */
  60.     REPEAT_TIMEOUT,        /* In the middle of a timeout */
  61.     REPEAT_PENDING,        /* Repeat should be taken next */
  62.     REPEAT_NONE              /* No repeat should happen */
  63. }                  repeatPhase = REPEAT_NONE;
  64.  
  65. static Mouse_Event    repeatEvent;    /* Event that will be repeated */
  66. static struct timeval     repeatTimeout;    /* Timeout to use for repeating */
  67. static unsigned int    repeatDelta;    /* Timeout length (ms) */
  68. #define REPEAT_LONG_TIMEOUT    500         /* Ms delay to begin repeat */
  69. #define REPEAT_SHORT_TIMEOUT    10         /* Ms delay to continue repeat */
  70.  
  71. static KbPrivRec      sysKbPriv = {
  72.     -1,                /* Type of keyboard */
  73.     -1,                /* Descriptor open to device */
  74.     spriteKbdGetEvents,        /* Function to read events */
  75.     spriteKbdProcessEvent,    /* Function to process an event */
  76.     spriteKbdDoneEvents,    /* Function called when all events */
  77.                 /* have been handled. */
  78.     0,                          /* Keycode offset */
  79.     &defaultKeyboardControl,    /* Current keyboard control */     
  80.     (pointer)NULL,            /* Private to keyboard (nothing needed) */
  81. };
  82.  
  83.  
  84. /*
  85.  *    XXX - Its not clear what to map these to for now.
  86.  *    keysyms.h doesn't define enough function key names.
  87.  */
  88.  
  89. #ifndef XK_L1
  90. #define    XK_L1    XK_Cancel
  91. #define    XK_L2    XK_Redo
  92. #define    XK_L3    XK_Menu
  93. #define    XK_L4    XK_Undo
  94. #define    XK_L5    XK_Insert
  95. #define    XK_L6    XK_Select
  96. #define    XK_L7    XK_Execute
  97. #define    XK_L8    XK_Print
  98. #define    XK_L9    XK_Find
  99. #define    XK_L10    XK_Help
  100. #define    XK_R1    NoSymbol
  101. #define    XK_R2    NoSymbol
  102. #define    XK_R3    NoSymbol
  103. #define    XK_R4    NoSymbol
  104. #define    XK_R5    NoSymbol
  105. #define    XK_R6    NoSymbol
  106. #define    XK_R7    NoSymbol
  107. #define    XK_R8    XK_Up
  108. #define    XK_R9    NoSymbol
  109. #define    XK_R10    XK_Left
  110. #define    XK_R11    XK_Home
  111. #define    XK_R12    XK_Right
  112. #define    XK_R13    NoSymbol
  113. #define    XK_R14    XK_Down
  114. #define    XK_R15    NoSymbol
  115. #endif
  116.  
  117. static KeySym sunKbdMap[] = {
  118.     XK_L1,        NoSymbol,        /* 0x01 */
  119.     NoSymbol,    NoSymbol,        /* 0x02 */
  120.     XK_L2,        NoSymbol,        /* 0x03 */
  121.     NoSymbol,    NoSymbol,        /* 0x04 */
  122.     XK_F1,        NoSymbol,        /* 0x05 */
  123.     XK_F2,        NoSymbol,        /* 0x06 */
  124.     NoSymbol,    NoSymbol,        /* 0x07 */
  125.     XK_F3,        NoSymbol,        /* 0x08 */
  126.     NoSymbol,    NoSymbol,        /* 0x09 */
  127.     XK_F4,        NoSymbol,        /* 0x0a */
  128.     NoSymbol,    NoSymbol,        /* 0x0b */
  129.     XK_F5,        NoSymbol,        /* 0x0c */
  130.     NoSymbol,    NoSymbol,        /* 0x0d */
  131.     XK_F6,        NoSymbol,        /* 0x0e */
  132.     NoSymbol,    NoSymbol,        /* 0x0f */
  133.     XK_F7,        NoSymbol,        /* 0x10 */
  134.     XK_F8,        NoSymbol,        /* 0x11 */
  135.     XK_F9,        NoSymbol,        /* 0x12 */
  136.     XK_Break,    NoSymbol,        /* 0x13 */
  137.     NoSymbol,    NoSymbol,        /* 0x14 */
  138.     XK_R1,        NoSymbol,        /* 0x15 */
  139.     XK_R2,        NoSymbol,        /* 0x16 */
  140.     XK_R3,        NoSymbol,        /* 0x17 */
  141.     NoSymbol,    NoSymbol,        /* 0x18 */
  142.     XK_L3,        NoSymbol,        /* 0x19 */
  143.     XK_L4,        NoSymbol,        /* 0x1a */
  144.     NoSymbol,    NoSymbol,        /* 0x1b */
  145.     NoSymbol,    NoSymbol,        /* 0x1c */
  146.     XK_Escape,    NoSymbol,        /* 0x1d */
  147.     XK_1,        XK_exclam,        /* 0x1e */
  148.     XK_2,        XK_at,            /* 0x1f */
  149.     XK_3,        XK_numbersign,        /* 0x20 */
  150.     XK_4,        XK_dollar,        /* 0x21 */
  151.     XK_5,        XK_percent,        /* 0x22 */
  152.     XK_6,        XK_asciicircum,        /* 0x23 */
  153.     XK_7,        XK_ampersand,        /* 0x24 */
  154.     XK_8,        XK_asterisk,        /* 0x25 */
  155.     XK_9,        XK_parenleft,        /* 0x26 */
  156.     XK_0,        XK_parenright,        /* 0x27 */
  157.     XK_minus,    XK_underscore,        /* 0x28 */
  158.     XK_equal,    XK_plus,        /* 0x29 */
  159.     XK_quoteleft,    XK_asciitilde,        /* 0x2a */
  160.     XK_BackSpace,    NoSymbol,        /* 0x2b */
  161.     NoSymbol,    NoSymbol,        /* 0x2c */
  162.     XK_R4,        NoSymbol,        /* 0x2d */
  163.     XK_R5,        NoSymbol,        /* 0x2e */
  164.     XK_R6,        NoSymbol,        /* 0x2f */
  165.     NoSymbol,    NoSymbol,        /* 0x30 */
  166.     XK_L5,        NoSymbol,        /* 0x31 */
  167.     NoSymbol,    NoSymbol,        /* 0x32 */
  168.     XK_L6,        NoSymbol,        /* 0x33 */
  169.     NoSymbol,    NoSymbol,        /* 0x34 */
  170.     XK_Tab,        NoSymbol,        /* 0x35 */
  171.     XK_Q,        NoSymbol,        /* 0x36 */
  172.     XK_W,        NoSymbol,        /* 0x37 */
  173.     XK_E,        NoSymbol,        /* 0x38 */
  174.     XK_R,        NoSymbol,        /* 0x39 */
  175.     XK_T,        NoSymbol,        /* 0x3a */
  176.     XK_Y,        NoSymbol,        /* 0x3b */
  177.     XK_U,        NoSymbol,        /* 0x3c */
  178.     XK_I,        NoSymbol,        /* 0x3d */
  179.     XK_O,        NoSymbol,        /* 0x3e */
  180.     XK_P,        NoSymbol,        /* 0x3f */
  181.     XK_bracketleft,    XK_braceleft,        /* 0x40 */
  182.     XK_bracketright,    XK_braceright,    /* 0x41 */
  183.     XK_Delete,    NoSymbol,        /* 0x42 */
  184.     NoSymbol,    NoSymbol,        /* 0x43 */
  185.     XK_R7,        NoSymbol,        /* 0x44 */
  186.     XK_Up,        XK_R8,            /* 0x45 */
  187.     XK_R9,        NoSymbol,        /* 0x46 */
  188.     NoSymbol,    NoSymbol,        /* 0x47 */
  189.     XK_L7,        NoSymbol,        /* 0x48 */
  190.     XK_L8,        NoSymbol,        /* 0x49 */
  191.     NoSymbol,    NoSymbol,        /* 0x4a */
  192.     NoSymbol,    NoSymbol,        /* 0x4b */
  193.     XK_Control_L,    NoSymbol,        /* 0x4c */
  194.     XK_A,        NoSymbol,        /* 0x4d */
  195.     XK_S,        NoSymbol,        /* 0x4e */
  196.     XK_D,        NoSymbol,        /* 0x4f */
  197.     XK_F,        NoSymbol,        /* 0x50 */
  198.     XK_G,        NoSymbol,        /* 0x51 */
  199.     XK_H,        NoSymbol,        /* 0x52 */
  200.     XK_J,        NoSymbol,        /* 0x53 */
  201.     XK_K,        NoSymbol,        /* 0x54 */
  202.     XK_L,        NoSymbol,        /* 0x55 */
  203.     XK_semicolon,    XK_colon,        /* 0x56 */
  204.     XK_quoteright,    XK_quotedbl,        /* 0x57 */
  205.     XK_backslash,    XK_bar,            /* 0x58 */
  206.     XK_Return,    NoSymbol,        /* 0x59 */
  207.     NoSymbol,    NoSymbol,        /* 0x5a */
  208.     XK_Left,    XK_R10,            /* 0x5b */
  209.     XK_R11,        NoSymbol,        /* 0x5c */
  210.     XK_Right,    NoSymbol,        /* 0x5d */
  211.     NoSymbol,    NoSymbol,        /* 0x5e */
  212.     XK_L9,        NoSymbol,        /* 0x5f */
  213.     NoSymbol,    NoSymbol,        /* 0x60 */
  214.     XK_L10,        NoSymbol,        /* 0x61 */
  215.     NoSymbol,    NoSymbol,        /* 0x62 */
  216.     XK_Shift_L,    NoSymbol,        /* 0x63 */
  217.     XK_Z,        NoSymbol,        /* 0x64 */
  218.     XK_X,        NoSymbol,        /* 0x65 */
  219.     XK_C,        NoSymbol,        /* 0x66 */
  220.     XK_V,        NoSymbol,        /* 0x67 */
  221.     XK_B,        NoSymbol,        /* 0x68 */
  222.     XK_N,        NoSymbol,        /* 0x69 */
  223.     XK_M,        NoSymbol,        /* 0x6a */
  224.     XK_comma,    XK_less,        /* 0x6b */
  225.     XK_period,    XK_greater,        /* 0x6c */
  226.     XK_slash,    XK_question,        /* 0x6d */
  227.     XK_Shift_R,    NoSymbol,        /* 0x6e */
  228.     XK_Linefeed,    NoSymbol,        /* 0x6f */
  229.     XK_R13,        NoSymbol,        /* 0x70 */
  230.     XK_Down,    XK_R14,            /* 0x71 */
  231.     XK_R15,        NoSymbol,        /* 0x72 */
  232.     NoSymbol,    NoSymbol,        /* 0x73 */
  233.     NoSymbol,    NoSymbol,        /* 0x74 */
  234.     NoSymbol,    NoSymbol,        /* 0x75 */
  235.     NoSymbol,    NoSymbol,        /* 0x76 */
  236.     XK_Caps_Lock,    NoSymbol,        /* 0x77 */
  237.     XK_Meta_L,    NoSymbol,        /* 0x78 */
  238.     XK_space,    NoSymbol,        /* 0x79 */
  239.     XK_Meta_R,    NoSymbol,        /* 0x7a */
  240.     NoSymbol,    NoSymbol,        /* 0x7b */
  241.     NoSymbol,    NoSymbol,        /* 0x7c */
  242.     NoSymbol,    NoSymbol,        /* 0x7d */
  243.     NoSymbol,    NoSymbol,        /* 0x7e */
  244.     NoSymbol,    NoSymbol,        /* 0x7f */
  245. };
  246.  
  247. static KeySymsRec sunMapDesc = {
  248. /*  map        minKeyCode  maxKeyCode  width */
  249.     sunKbdMap,      1,        0x7a,    2
  250. };
  251.  
  252. #define    cT    (ControlMask)
  253. #define    sH    (ShiftMask)
  254. #define    lK    (LockMask)
  255. #define    mT    (Mod1Mask)
  256. static CARD8 sunModMap[MAP_LENGTH] = {
  257.     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 00-0f */
  258.     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 10-1f */
  259.     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 20-2f */
  260.     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 30-3f */
  261.     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 40-4f */
  262.     0,  0,  0,  cT, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 50-5f */
  263.     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  sH, 0,  0,  0,  0,  0, /* 60-6f */
  264.     0,  0,  0,  0,  0,  sH, 0,  0,  0,  0,  0,  0,  0,  0,  lK, mT,/* 70-7f */
  265.     0,  mT, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 80-8f */
  266.     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 90-9f */
  267.     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* a0-af */
  268.     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* b0-bf */
  269.     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* c0-cf */
  270.     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* d0-df */
  271.     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* e0-ef */
  272.     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* f0-ff */
  273. };
  274.  
  275.  
  276. /*-
  277.  *-----------------------------------------------------------------------
  278.  * spriteKbdProc --
  279.  *    Handle the initialization, etc. of a keyboard.
  280.  *
  281.  * Results:
  282.  *    None.
  283.  *
  284.  * Side Effects:
  285.  *    None.
  286.  *
  287.  *-----------------------------------------------------------------------
  288.  */
  289. /*ARGSUSED*/
  290. int
  291. spriteKbdProc (pKeyboard, what, argc, argv)
  292.     DevicePtr      pKeyboard;    /* Keyboard to manipulate */
  293.     int              what;            /* What to do to it */
  294.     int              argc;
  295.     char          **argv;
  296. {
  297.     register int  fd;
  298.     int          tmp;
  299.     KbPrivPtr      pPriv;
  300.     int              i;
  301.     char      reset = KBD_RESET;
  302.     BYTE          map[MAP_LENGTH];
  303.  
  304.     switch (what) {
  305.     case DEVICE_INIT:
  306.         if (pKeyboard != LookupKeyboardDevice()) {
  307.         ErrorF ("Cannot open non-system keyboard");
  308.         return (!Success);
  309.         }
  310.         /*
  311.          * First open and find the current state of the keyboard
  312.          * If we are reinitializing, then turn the device OFF first.
  313.          */
  314.         if (sysKbPriv.fd >= 0) {
  315.         fd = sysKbPriv.fd;
  316.         } else {
  317.             ReturnStatus status;
  318.  
  319.         status = Fs_Open("/dev/mouse",
  320.             FS_NON_BLOCKING|FS_READ|FS_WRITE, 0, &sysKbPriv.fd);
  321.             if (status != 0) {
  322.             errno = Compat_MapCode(status);
  323.             Error ("Opening /dev/mouse");
  324.             return (!Success);
  325.         }
  326.         fd = sysKbPriv.fd;
  327.         }
  328.  
  329.         /*
  330.          * Perform final initialization of the system private keyboard
  331.          * structure and fill in various slots in the device record
  332.          * itself which couldn't be filled in before.
  333.          */
  334.         pKeyboard->devicePrivate = (pointer)&sysKbPriv;
  335.  
  336.         pKeyboard->on = FALSE;
  337.         /*
  338.          * Make sure keycodes we send out are >= MIN_KEYCODE
  339.          */
  340.          if (sunMapDesc.minKeyCode < MIN_KEYCODE) {
  341.          int    offset;
  342.  
  343.          offset = MIN_KEYCODE - sunMapDesc.minKeyCode;
  344.          sunMapDesc.minKeyCode += offset;
  345.          sunMapDesc.maxKeyCode += offset;
  346.          sysKbPriv.offset = offset;
  347.          }
  348.  
  349.         InitKeyboardDeviceStruct(pKeyboard, &sunMapDesc, sunModMap,
  350.                      spriteBell, spriteKbdCtrl);
  351.  
  352.         /*
  353.          * Reset keyboard to avoid spurious events (No!  don't do now:
  354.          * doesn't work in Sprite).
  355.         (void) write(fd, &reset, 1);
  356.          */
  357.         break;
  358.     case DEVICE_ON:
  359.         pKeyboard->on = TRUE;
  360.         AddEnabledDevice(((KbPrivPtr)pKeyboard->devicePrivate)->fd);
  361.         /*
  362.          * Initialize auto-repeat.
  363.          */
  364.         repeatPhase = REPEAT_NONE;
  365.         break;
  366.     case DEVICE_CLOSE:
  367.     case DEVICE_OFF:
  368.         pKeyboard->on = FALSE;
  369.         RemoveEnabledDevice(((KbPrivPtr)pKeyboard->devicePrivate)->fd);
  370.         /*
  371.          * Make sure auto-repeat doesn't generate events now that the
  372.          * keyboard is off.
  373.          */
  374.         repeatPhase = REPEAT_NONE;
  375.         break;
  376.     }
  377.     return (Success);
  378. }
  379.  
  380. /*-
  381.  *-----------------------------------------------------------------------
  382.  * spriteBell --
  383.  *    Ring the terminal/keyboard bell
  384.  *
  385.  * Results:
  386.  *    None.
  387.  *
  388.  * Side Effects:
  389.  *    None, really...
  390.  *
  391.  *-----------------------------------------------------------------------
  392.  */
  393. static void
  394. spriteBell (loudness, pKeyboard)
  395.     int              loudness;        /* Percentage of full volume */
  396.     DevicePtr      pKeyboard;        /* Keyboard to ring */
  397. {
  398.     KbPrivPtr        pPriv = (KbPrivPtr)pKeyboard->devicePrivate;
  399.     char        kbdCmd;
  400.     struct timeval    sleepTime;
  401.  
  402.     if (loudness == 0) {
  403.     return;
  404.     }
  405.  
  406.     kbdCmd = KBD_BELL_ON;
  407.     (void) write(pPriv->fd, &kbdCmd, 1);
  408.  
  409.     sleepTime.tv_usec = pPriv->ctrl->bell_duration * 1000;
  410.     sleepTime.tv_sec = 0;
  411.     while (sleepTime.tv_usec >= 1000000) {
  412.     sleepTime.tv_sec += 1;
  413.     sleepTime.tv_usec -= 1000000;
  414.     }
  415.     (void) select(0, (int *) 0, (int *) 0, (int *) 0, &sleepTime);
  416.  
  417.     kbdCmd = KBD_BELL_OFF;
  418.     (void) write(pPriv->fd, &kbdCmd, 1);
  419. }
  420.  
  421. /*-
  422.  *-----------------------------------------------------------------------
  423.  * spriteKbdCtrl --
  424.  *    Alter some of the keyboard control parameters
  425.  *
  426.  * Results:
  427.  *    None.
  428.  *
  429.  * Side Effects:
  430.  *    Some...
  431.  *
  432.  *-----------------------------------------------------------------------
  433.  */
  434. static void
  435. spriteKbdCtrl (pKeyboard, ctrl)
  436.     DevicePtr      pKeyboard;        /* Keyboard to alter */
  437.     KeybdCtrl      *ctrl;            /* New control info */
  438. {
  439.     KbPrivPtr      pPriv;
  440.     char      kbCmd;
  441.  
  442.     pPriv = (KbPrivPtr)pKeyboard->devicePrivate;
  443.  
  444.     pPriv->ctrl = ctrl;
  445.     if (ctrl->click) {
  446.     kbCmd = KBD_CLICK_ON;
  447.     } else {
  448.     kbCmd = KBD_CLICK_OFF;
  449.     }
  450.  
  451.     (void) write(pPriv->fd, &kbCmd, 1);
  452.  
  453.     if (!ctrl->autoRepeat) {
  454.     repeatPhase = REPEAT_NONE;
  455.     }
  456. }
  457.  
  458. /*-
  459.  *-----------------------------------------------------------------------
  460.  * spriteKbdGetEvents --
  461.  *    Return the events waiting in the wings for the given keyboard.
  462.  *
  463.  * Results:
  464.  *    A pointer to an array of Firm_events or (Firm_event *)0 if no events
  465.  *    The number of events contained in the array.
  466.  *
  467.  * Side Effects:
  468.  *    None.
  469.  *-----------------------------------------------------------------------
  470.  */
  471. static Mouse_Event *
  472. spriteKbdGetEvents (pKeyboard, pNumEvents)
  473.     DevicePtr      pKeyboard;        /* Keyboard to read */
  474.     int              *pNumEvents;        /* Place to return number of events */
  475. {
  476.     static Mouse_Event    evBuf[MAXEVENTS];   /* Buffer for input events */
  477.  
  478.     if (repeatPhase == REPEAT_PENDING) {
  479.     /*
  480.      * This will only have been set if no streams were really ready, thus
  481.      * there are no events to read from /dev/mouse.
  482.      */
  483.     repeatEvent.flags |= KEY_UP;
  484.     repeatEvent.time += repeatDelta / 2;
  485.     evBuf[0] = repeatEvent;
  486.  
  487.     repeatEvent.flags &= ~KEY_UP;
  488.     repeatEvent.time += repeatDelta / 2;
  489.     evBuf[1] = repeatEvent;
  490.  
  491.     *pNumEvents = 2;
  492.  
  493.     repeatPhase = REPEAT_SHORT;
  494.     } else {
  495.     int              nBytes;    /* number of bytes of events available. */
  496.     KbPrivPtr      pPriv;
  497.     int              i;
  498.     
  499.     pPriv = (KbPrivPtr) pKeyboard->devicePrivate;
  500.     nBytes = read(pPriv->fd, (char *) evBuf, sizeof(evBuf));
  501.     if (nBytes >= 0) {
  502.         *pNumEvents = nBytes / sizeof (Mouse_Event);
  503.     } else if (errno == EWOULDBLOCK) {
  504.         *pNumEvents = 0;
  505.     } else {
  506.         FatalError ("Could not read the keyboard");
  507.     }
  508.     }
  509.     return (evBuf);
  510. }
  511.  
  512.  
  513. /*-
  514.  *-----------------------------------------------------------------------
  515.  * spriteKbdProcessEvent --
  516.  *    Transform a Sprite event into an X one.
  517.  *
  518.  * Results:
  519.  *    None.
  520.  *
  521.  * Side Effects:
  522.  *    An event is passed to DIX. The last key press event is stored in
  523.  *    repeatEvent and repeatPhase set to REPEAT_INITIAL if we're doing
  524.  *    autorepeat and the key is to be repeated.
  525.  *
  526.  *-----------------------------------------------------------------------
  527.  */
  528. static void
  529. spriteKbdProcessEvent (pKeyboard, ev)
  530.     DevicePtr      pKeyboard;
  531.     Mouse_Event  *ev;
  532. {
  533.     xEvent        xE;
  534.     register KbPrivPtr    pPriv;
  535.     register int      smask;
  536.     PtrPrivPtr          ptrPriv;
  537.  
  538.     pPriv = (KbPrivPtr)pKeyboard->devicePrivate;
  539.     ptrPriv = (PtrPrivPtr) LookupPointerDevice()->devicePrivate;
  540.  
  541.     xE.u.keyButtonPointer.time = ev->time;
  542.     xE.u.keyButtonPointer.rootX = ptrPriv->x;
  543.     xE.u.keyButtonPointer.rootY = ptrPriv->y;
  544.     xE.u.u.detail = ev->key + pPriv->offset;
  545.     if (ev->key == ALL_KEYS_UP) {
  546.     xE.u.u.type = KeyRelease;
  547.     repeatPhase = REPEAT_NONE;
  548.     } else if (ev->flags & KEY_UP) {
  549.     xE.u.u.type = KeyRelease;
  550.     if (!(ev->flags & AUTO_GENERATED) &&
  551.          (repeatPhase != REPEAT_NONE) &&
  552.          (repeatEvent.key == ev->key)) {
  553.         /*
  554.          * Turn off repeat if we got a real up event for the key
  555.          * being repeated
  556.          */
  557.         repeatPhase = REPEAT_NONE;
  558.     }
  559.     } else {
  560.     xE.u.u.type = KeyPress;
  561.     if ((repeatPhase != REPEAT_SHORT) &&
  562.         (pPriv->ctrl->autoRepeat ||
  563.          Bit_IsSet (xE.u.u.detail, pPriv->ctrl->autoRepeats))) {
  564.          repeatEvent = *ev;
  565.          repeatEvent.flags |= AUTO_GENERATED;
  566.          repeatPhase = REPEAT_LONG;
  567.     }
  568.     }
  569.  
  570.     (* pKeyboard->processInputProc) (&xE, pKeyboard);
  571. }
  572.  
  573. /*-
  574.  *-----------------------------------------------------------------------
  575.  * spriteDoneEvents --
  576.  *    Nothing to do, here...
  577.  *
  578.  * Results:
  579.  *
  580.  * Side Effects:
  581.  *
  582.  *-----------------------------------------------------------------------
  583.  */
  584. static void
  585. spriteKbdDoneEvents (pKeyboard, final)
  586.     DevicePtr      pKeyboard;
  587.     Bool      final;
  588. {
  589. }
  590.  
  591. /*-
  592.  *-----------------------------------------------------------------------
  593.  * LegalModifier --
  594.  *    See if a key is legal as a modifier. We're very lenient around,
  595.  *    here, so we always return true.
  596.  *
  597.  * Results:
  598.  *    TRUE.
  599.  *
  600.  * Side Effects:
  601.  *    None.
  602.  *
  603.  *-----------------------------------------------------------------------
  604.  */
  605. Bool
  606. LegalModifier (key)
  607.     int        key;
  608. {
  609.     return (TRUE);
  610. }
  611.  
  612. /*-
  613.  *-----------------------------------------------------------------------
  614.  * spriteBlockHandler --
  615.  *    Tell the OS layer when to timeout to implement auto-repeat.
  616.  *
  617.  * Results:
  618.  *    None.
  619.  *
  620.  * Side Effects:
  621.  *    The timeout value may be overwritten.
  622.  *
  623.  *-----------------------------------------------------------------------
  624.  */
  625. void
  626. spriteBlockHandler (index, pKeyboard, ppTime, pReadMask)
  627.     int                index;        /* Screen index */
  628.     DevicePtr        pKeyboard;    /* Keyboard for which to do auto-repeat */
  629.     struct timeval  **ppTime;     /* Pointer to timeout to use */
  630.     int                *pReadMask;    /* Mask the OS Layer will use for select. */
  631. {
  632.     if (repeatPhase == REPEAT_LONG) {
  633.     /*
  634.      * Beginning long timeout
  635.      */
  636.     repeatDelta = REPEAT_LONG_TIMEOUT;
  637.     } else if (repeatPhase == REPEAT_SHORT) {
  638.     /*
  639.      * Beginning short timeout
  640.      */
  641.     repeatDelta = REPEAT_SHORT_TIMEOUT;
  642.     } else if (repeatPhase == REPEAT_NONE) {
  643.     /*
  644.      * No repeat necessary -- it can block as long as it wants to
  645.      */
  646.     return;
  647.     } else if (repeatPhase == REPEAT_TIMEOUT) {
  648.     /*
  649.      * Interrupted timeout -- use old timeout (that was modified by
  650.      * select in the OS layer)
  651.      */
  652.     *ppTime = &repeatTimeout;
  653.     return;
  654.     }
  655.     repeatTimeout.tv_sec = repeatDelta / 1000;
  656.     repeatTimeout.tv_usec = repeatDelta * 1000;
  657.     repeatPhase = REPEAT_TIMEOUT;
  658.     *ppTime = &repeatTimeout;
  659. }
  660.  
  661. /*-
  662.  *-----------------------------------------------------------------------
  663.  * spriteWakeupHandler --
  664.  *    Figure out if should do a repeat when the server wakes up. Because
  665.  *    select will modify repeatTimeout to contain the time left, we
  666.  *    can tell if the thing timed out.
  667.  *
  668.  * Results:
  669.  *    None.
  670.  *
  671.  * Side Effects:
  672.  *    repeatPhase may be changed to REPEAT_PENDING. If it is, *pNumReady
  673.  *    will be set to 1 and the keyboard's stream marked ready in the
  674.  *    result mask.
  675.  *
  676.  *-----------------------------------------------------------------------
  677.  */
  678. void
  679. spriteWakeupHandler (index, pKeyboard, pNumReady, pReadMask)
  680.     int              index;        /* Screen index */
  681.     DevicePtr      pKeyboard;    /* Keyboard to repeat */
  682.     int              *pNumReady;     /* Pointer to number of ready streams */
  683.     int              *pReadMask;    /* Ready streams */
  684. {
  685.     KbPrivPtr      pPriv;
  686.  
  687.     pPriv = (KbPrivPtr)pKeyboard->devicePrivate;
  688.     
  689.     if ((repeatPhase == REPEAT_TIMEOUT) && (*pNumReady == 0)) {
  690.     repeatPhase = REPEAT_PENDING;
  691.     Bit_Set (pPriv->fd, pReadMask);
  692.     *pNumReady = 1;
  693.     }
  694. }
  695.